
using namespace System;

#define Show(x) Console::WriteLine(x)
#define SHOW Console::WriteLine(__FUNCTION__);

public class N
{
public:
   N(){Show("N::ctor");}
   ~N(){Show("N::dtor");}
};
ref class RC
{
public:
	RC(){Show("RC::ctor");}
	~RC(){Show("RC::dctor");}
};
value class VC
{
public:
	//VC(){Show("VC::ctor");}
	//~VC(){Show("VC::ctor");}
};

public ref class MyTest
{
public:
	void Test1()
    {
		SHOW;
		int x = 5;
        array<int>^ strarray = gcnew array<int>(x);
        for(int i = 0; i < x; ++i)
            strarray[i] = i * 10;
        for(int i = 0; i < x; ++i)
            Console::WriteLine(strarray[i]);
    }
    void Test2()
    {
		SHOW;
		int x = 5;
        array<String^>^ strarray = gcnew array<String^>(x);
        for(int i = 0; i < x; ++i)
            strarray[i] = String::Concat("Number ",i.ToString());
        for(int i = 0; i < x; ++i)
            Console::WriteLine(strarray[i]);
    }
	void Test3()
	{
		SHOW;
		int x = 5;
		array<RC^>^ strarray = gcnew array<RC^>(x);
        for(int i = 0; i < x; ++i)
            strarray[i] = gcnew RC; 

		//// error can not use this type here without a top-level^
		//SHOW;
		//array<RC>^ strarray2 = gcnew array<RC>(x);
  //      for(int i = 0; i < x; ++i)
		//{
		//	RC r;
  //          strarray2[i] = r; 
		//}
	}
	void Test4()
	{
		SHOW;
		int x = 5;
		array<VC>^ arr = gcnew array<VC>(x);
		for(int i = 0; i < x; ++i)
		{
			VC vc;
			arr[i] = vc;
		}
	}
	void Test5()
	{
		SHOW;
		array<N*>^ arr = gcnew array<N*>(3);
		for(int i=0; i<arr->Length; i++)   
		 arr[i] = new N();
	}   
    void Test6()
	{
		SHOW;
		array<array<int>^>^ arr = gcnew array<array<int>^> (5); 

		for(int i=0, j=10; i < 5; i++, j+=10)
		{
		  arr[i] = gcnew array<int> (j);
		}
		Console::WriteLine("Rank = {0}; Length = {1}",
		  arr->Rank,arr->Length);
		for(int i=0; i<5; i++)
		  Console::WriteLine("Rank = {0}; Length = {1}",
			arr[i]->Rank,arr[i]->Length);   
	}
	void Test7()
    {
		SHOW;
        array<String^,2>^ names = gcnew array<String^,2>(4,2);
        names[0,0] = "John";
        names[1,0] = "Tim";
        names[2,0] = "Nancy";
        names[3,0] = "Anitha";
        for(int i = 0; i < 4; i++)
            if(i%2==0)
                names[i,1] = "Brown";
            else
                names[i,1] = "Wilson";
        for(int i = 0; i < 4; ++i)
            Console::WriteLine("{0} {1}",names[i,0],names[i,1]);

		Console::WriteLine("Length is:{0}",names->Length);
    }
    void Test8(String^ s, [ParamArray] array<int>^ arr )    
    {
		SHOW;
        Console::Write(s);
        for(int i=0; i<arr->Length; i++)
            Console::Write(" {0}",arr[i]);
        Console::WriteLine();
    }
    void Test9()
	{
		SHOW;
		//Single dimensional arrays
		array<String^>^ arr1 = gcnew array<String^> {"Nish", "Colin"};
		array<String^>^ arr2 = {"Nish", "Smitha"};
	    
		//Multi dimensional arrays
		array<Object^,2>^ multiobarr = {{"Nish", 100}, {"Jambo", 200},{"jason", 200}};

		Console::WriteLine(arr1.Length);
		Console::WriteLine(arr2.Length);
		Console::WriteLine(multiobarr.Length);
	}
};

int main(array<System::String ^> ^args)
{
    MyTest^ r = gcnew MyTest();
    r->Test1();
    r->Test2();
    r->Test3();
    r->Test4();
    r->Test5();
    r->Test6();
    r->Test7();
	r->Test8("Nish",1,25,100);
	r->Test9();

    return 0;
}